/**
 * @file ExperiDefs.h
 * @author w (w@163.com)
 * @brief 试验宏定义
 * @version 0.1
 * @date 2024-04-28
 *
 * @copyright Copyright (c) 2024 xxxx公司
 *
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version <th>Author  <th>Description
 * <tr><td>2024-04-28 <td>v1.0     <td>chen     <td>内容
 * </table>
 */
#ifndef EXPERIDEFS_H
#define EXPERIDEFS_H

#include <string>
#include <iostream>

/**
 * @brief 试验消息版本
 *
 * @details
 */
#ifndef EXPERI_MSG_VERSION
#define EXPERI_MSG_VERSION "1.0"
#endif // EXPERI_MSG_VERSION

/**
 * @brief 默认试验ID
 *
 * @details
 */
#ifndef DEFAULT_EXPERI_ID
#define DEFAULT_EXPERI_ID "default"
#endif // DEFAULT_EXPERI_ID

/**
 * @brief 日志级别
 *
 * @details
 */
namespace ExperiLogLevel {
	/**
	 * @brief 日志级别
	 *
	 * @details
	 */
	typedef enum ELevel {
		Debug = 1, /*!<debug*/
		Info = 2, /*!<Info*/
		Warning = 3, /*!<Warning*/
		Error = 4, /*!<Error*/
		Fatal = 5, /*!<Fatal*/
	} Level;
} // namespace ExperiLogLevel

/**
 * @brief 试验指令消息Json格式 key标识
 *
 * @details
 */
namespace ExperiJsonKey {
	static const std::string APP_CODE("app_code"); ///< 试验应用名称
	static const std::string APP_ID("apps"); ///< 试验应用id
	static const std::string CMD("cmd"); ///< 试验指令
	static const std::string DATA("data"); ///< 试验消息data对象字段
	static const std::string EXPER_ID("exper_id"); ///< 试验id
	static const std::string LEVEL("level"); ///< 日志级别
	static const std::string LOGIC_TIME("logic_time"); ///< 逻辑时间
	static const std::string SAMPLE("sample"); ///< 样本文件
	static const std::string STATE("state"); ///< 态
	static const std::string TIMESTAMP("timestamp"); ///< 时间戳
	static const std::string VERSION("version"); ///< 协议版本
	static const std::string FN_CODE("code"); ///< 方法代码
	static const std::string MESSAGE("message"); ///< 成功失败消息
	static const std::string FUNCTION_NAME("function_name"); ///< 初始化方法名称
	static const std::string VOM_NAME("vom_name"); ///< 模型名称
	static const std::string EXPERIDOMAINS("domains"); ///< 试验域(复数)
	static const std::string EXPERIDOMAIN("domain"); ///< 试验域(单数)
	static const std::string TRACE_ID("trace_id"); ///< 试验任务对应的初始化文件
	static const std::string DOWNLOADURL("url"); ///< 试验任务对应的初始化文件
} // namespace ExperiJsonKey

/**
 * 试验命令枚举定义.
 */
namespace ExperimentCmd {
	typedef enum {
		EXPERIMENT_INIT = 2001, ///< 试验初始化
		EXPERIMENT_START = 2002, ///< 试验开始
		EXPERIMENT_END = 2003, ///< 试验停止 结束本次试验任务，等待新的试验任务
		EXPERIMENT_PAUSE = 2004, ///< 试验暂停 停止向前推进
		EXPERIMENT_CONTINUE = 2005, ///< 试验恢复(原先暂定的试验继续执行)
		APPLICATION_RESUMER = 2006, ///< 应用恢复
		EXPERIMENT_EXIT = 2009, ///< 试验退出  程序退出 不考虑 web维护
		AGENT_EXIT = 3000 ///< agent程序退出
	} EExperimentCmd;
}

/**
 * @brief 调试类
 *
 * @details 增加以下宏用于debug
 */
class DWTrace {
public:
	explicit DWTrace(const std::string& msg)
	    : m_msg(msg) {
		std::cout << "{ BEGIN " << m_msg << std::endl;
	}

	~DWTrace() {
		std::cout << "}} END  " << m_msg << std::endl;
	}

private:
	DWTrace(const DWTrace&);
	DWTrace& operator=(const DWTrace&);
	std::string m_msg;
};

#ifndef FUNCTION_TRACE
#define FUNCTION_TRACE DWTrace myTrace(__FUNCTION__);
#endif

#ifndef __FILENAME__
#define __FILENAME__                                         \
	(strrchr(__FILE__, '\\') ? (strrchr(__FILE__, '\\') + 1) \
	                         : ((strrchr(__FILE__, '/')) ? (strrchr(__FILE__, '/') + 1) : (__FILE__)))
#endif // __FILENAME__
#ifndef __COMMON_LOG__
#define __COMMON_LOG__ " [" << __FILENAME__ << ", " << __LINE__ << "]"
#endif // __COMMON_LOG__

#ifndef LOG_TRACE
#define LOG_TRACE(msg) std::cout << " TRACE :: " << msg << std::endl;
#endif // !LOG_TRACE

#ifndef LOG_MSG
#define LOG_MSG(msg) std::cout << "[MSG] " << msg << __COMMON_LOG__ << std::endl;
#endif // !LOG_MSG

#ifndef ERROR_MSG
#define ERROR_MSG(msg) std::cout << "[ERROR] " << msg << __COMMON_LOG__ << std::endl;
#endif // !ERROR_MSG

#ifndef BOOT_TRACE
#define BOOT_TRACE(msg) std::cout << "  >>>> " << msg << std::endl;
#endif // !BOOT_TRACE

#ifndef CLOSE_TRACE
#define CLOSE_TRACE(msg)                         \
	std::cout << "  <<<< ]" << msg << std::endl; \
	WRITE_MSG(msg);
#endif
#endif // EXPERIDEFS_H
